package cn.js189.uqc.util;

import cn.js189.common.constants.HttpConstant;
import cn.js189.common.constants.ProvOrderConst;
import cn.js189.common.constants.RyUrlConstants;
import cn.js189.common.util.StringUtils;
import cn.js189.common.util.helper.UUIDHelper;
import cn.js189.uqc.domain.req.HttpGetWithEntity;
import com.google.gson.Gson;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.js189.common.constants.CouponUrlConstant.E_COUPON_GENERATOR_SIGN_URL;
import static cn.js189.uqc.util.GuidGenerator.genRandomGUID;
import static cn.js189.uqc.util.SSLClientAF43.createSSLClientDefault;


/**
 * <Description> <br>
 *
 * @author zhangpzh<br>
 * @version 1.0<br>
 */
public final class HttpClientUtils {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtils.class);

    /** The rest template. */
    private static RestTemplate restTemplate;

    /**
     * http客户端
     */
    private static HttpClient httpClient;

    /**
     * 私有构造函数
     */
    private HttpClientUtils() {

    }

    static {
        // 长连接保持30秒
        PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(
		        30, TimeUnit.SECONDS);
        // 总连接数
        pollingConnectionManager.setMaxTotal(HttpConstant.MAX_TOTAL);
        // 同路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(HttpConstant.ROUTE_SIZE);

        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        // 重试次数，默认是3次，没有开启
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(1, true));
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());

        RequestConfig.Builder builder = RequestConfig.custom();
        builder.setConnectionRequestTimeout(HttpConstant.REQUEST_TIMEOUT);
        builder.setConnectTimeout(HttpConstant.CONNECT_TIMEOUT);
        builder.setSocketTimeout(HttpConstant.SOCKET_TIMEOUT);
        RequestConfig requestConfig = builder.build();
        httpClientBuilder.setDefaultRequestConfig(requestConfig);

        List<Header> headers = new ArrayList<Header>();
        String requestTime = DateUtils.getDateString(new Date(), DateUtils.STRING_DATE_FORMAT);
        headers.add(new BasicHeader("bssSysId", " DEFAULT_INTERFACE_USER"));
        headers.add(new BasicHeader("bssSign", MD5Utils.mD5("DEFAULT_INTERFACE_USER" + requestTime + "12321")));
        headers.add(new BasicHeader("bssReqTime", requestTime));
        httpClientBuilder.setDefaultHeaders(headers);

        httpClient = httpClientBuilder.build();

        // httpClient连接配置，底层是配置RequestConfig
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

        // // 添加内容转换器
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        messageConverters.add(new FormHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        //
        restTemplate = new RestTemplate();
        restTemplate.setMessageConverters(messageConverters);
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
        LOGGER.debug("RestClient初始化完成");
    }

    /**
     * Description: restTemplate post请求 form表单<br>
     *
     * @author zhangpzh<br>
     * @param url 地址
     * @param formParams form
     * @return <br>
     */
    public static String doPostMap(String url, Map<String, String> formParams) {
        LOGGER.info("请求url：{}",url);
        try {
            MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
            for (Map.Entry<String, String> entry : formParams.entrySet()) {
                requestEntity.add(entry.getKey(), MapUtils.getString(formParams, entry.getKey(), ""));
            }
            LOGGER.info("入参：{}",new Gson().toJson(formParams));
            return restTemplate.postForObject(url, requestEntity, String.class);
        } catch (Exception e) {
            LOGGER.error("POST请求出错：{ }", url, e);
        }

        return Strings.EMPTY;
    }

    /**
     * Description: restTemplate post JSON 请求<br>
     *
     * @author zhangpzh<br>
     * @param url 地址
     * @param jsonString json字符串
     * @return <br>
     */
    public static String doPostJSONold(String url, String jsonString) {
        LOGGER.info("请求url：{}",url);
        try {
            HttpEntity request = new HttpEntity(jsonString);
            LOGGER.info("入参：{}",jsonString);
            return restTemplate.postForObject(url, request, String.class);
        } catch (Exception e) {
            LOGGER.debug("POST请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    public static String doPostJSONHttps(String url,String jsonString){
        LOGGER.info("请求url：{}",url);
        LOGGER.info("入参：{}",jsonString);
        try(CloseableHttpClient httpClient = createSSLClientDefault()){
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(jsonString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", "application/json; charset=UTF-8");
            HttpResponse response = httpClient.execute(post);
            org.apache.http.HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, HttpConstant.UTF_ENCODING);
        }catch(Exception e){
            return "";
        }
    }

    public static String doPostJsonWithHeaders(String url, String jsonString, HttpHeaders headers){
        try {
            HttpEntity<String> entity = new HttpEntity<>(jsonString, headers);
            return restTemplate.postForObject(url, entity, String.class);

        } catch (Exception e) {
            LOGGER.debug("POST请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    public static String doPostXmlHttps(String url,String xmlString){
        LOGGER.info("请求url：{}",url);
        LOGGER.info("入参：{}",xmlString);
        try(CloseableHttpClient httpClient = createSSLClientDefault()){
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(xmlString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", "application/xml; charset=UTF-8");
            HttpResponse response = httpClient.execute(post);
            org.apache.http.HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, HttpConstant.UTF_ENCODING);
        }catch(Exception e){
            return "";
        }
    }

    /**
     * 新EOP调用带X-APP-ID和X-APP-KEY
     * Description: <br>
     *
     * @author yangyang<br>
     * 2020年7月13日
     * @return String<br>
     */
    public static String doPostJSONHttpsNewEOP(String url,String jsonString){
        LOGGER.info("请求url：{}",url);
        LOGGER.info("入参：{}",jsonString);
        try(CloseableHttpClient httpClient = createSSLClientDefault()){
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(jsonString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", "application/json; charset=UTF-8");
            post.setHeader("X-APP-ID",EInvoiceUtil.EOP_APP_KEY);
            post.setHeader("X-APP-KEY",EInvoiceUtil.EOP_APP_SECRET);
            post.setHeader("X-CTG-Request-ID",UUID.randomUUID().toString());
            HttpResponse response = httpClient.execute(post);
            org.apache.http.HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, HttpConstant.UTF_ENCODING);
        }catch(Exception e){
            return "";
        }
    }



    /**
     * Description: http POST 文本请求<br>
     *
     * @author zhangpzh<br>
     * @param url 地址
     * @param requestString 请求参数
     * @param encoding 编码
     * @return <br>
     */
    public static String doHttpPost(String url, String requestString, String encoding) {
        try {
            LOGGER.info("请求url：{}",url);
            LOGGER.info("入参：{}",requestString);
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(requestString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", "text/xml; charset=UTF-8");
            HttpResponse response = httpClient.execute(post);
            org.apache.http.HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, encoding);
        } catch (Exception e) {
            LOGGER.error("HttpClient Post请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    public static String doHttpPostMap(String url, Map<String, String> formParams) {
        try {
            HttpPost post = new HttpPost(url);
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : formParams.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), MapUtils.getString(formParams, entry.getKey(), "")));
            }
            post.setEntity(new UrlEncodedFormEntity(list, HttpConstant.UTF_ENCODING));
            HttpResponse httpResponse = httpClient.execute(post);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String st = EntityUtils.toString(httpResponse.getEntity());
                LOGGER.debug("调用外部接口响应参数：{}", st);
                return st;
            } else {
                LOGGER.debug("调用外部接口失败！！：HttpStatus{}", httpResponse.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            LOGGER.error("POST请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }
    
    /**
     * Description: restTemplate post JSON 请求<br>
     *
     * @author zhangpzh<br>
     * @param url 地址
     * @param jsonString json字符串
     * @return <br>
     */
    public static String doPostJSON(String url, String jsonString) {
        try {
            LOGGER.info("请求url：{}",url);
            LOGGER.info("请求入参：{}",jsonString);
            HttpEntity request = new HttpEntity(jsonString);
            String result = restTemplate.postForObject(url, request, String.class);
            LOGGER.debug("post出参:{}",result);
            return result;
        } catch (Exception e) {
            LOGGER.debug("POST请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    /**
     * Description: http POST <br>
     *
     * @author shenfan<br>
     * @param url 地址
     * @param requestString 请求参数
     * @param encoding 编码
     * @param contentType 传输文本类型
     * @return <br>
     */
    public static String doHttpPostV2(String url, String requestString, String encoding, String contentType) {
        try {
            LOGGER.info("请求url：{}",url);
            LOGGER.info("入参：{}",requestString);
            long startTime = System.currentTimeMillis();
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(requestString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", contentType +"; charset=UTF-8");
            HttpResponse response = httpClient.execute(post);
            long endTime = System.currentTimeMillis();
            LOGGER.debug("post请求时间:{}", (endTime - startTime));
            org.apache.http.HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, encoding);
        } catch (Exception e) {
            LOGGER.debug("HttpClient Post请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    public static String sendPost(String url, String param) {
    	LOGGER.info("请求url：{},入参：{},isproxy:{}",url,param);
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder sb = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST"); // POST方法

            // 设置通用的请求属性

            for (Map.Entry<String, String> entry : setProperty(null).entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.connect();

            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
            // 发送请求参数
            out.write(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK
                    || conn.getResponseCode() == HttpURLConnection.HTTP_CREATED
                    || conn.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            } else {
                in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
            }
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
        } catch (Exception e) {
            LOGGER.debug("发送 POST 请求出现异常！{}", e.getMessage());
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                LOGGER.debug(ex.getMessage());
            }
        }
        return sb.toString();
    }
    
    
    public static String sendPost(String url, String param, boolean isproxy) {
        LOGGER.info("请求url：{},入参：{},isproxy:{}",url,param,isproxy);
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder sb = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST"); // POST方法
            
            // 设置通用的请求属性
            
            for (Map.Entry<String, String> entry : setProperty(null).entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.connect();
            
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
            // 发送请求参数
            out.write(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK
                    || conn.getResponseCode() == HttpURLConnection.HTTP_CREATED
                    || conn.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            } else {
                in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
            }
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
        } catch (Exception e) {
            LOGGER.debug("发送 POST 请求出现异常！{}", e.getMessage());
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                LOGGER.debug(ex.getMessage());
            }
        }
        return sb.toString();
    }
    
	//设置请求头属性
	public static Map<String, String> setProperty(Map<String, String> map) {

		HashMap<String, String> pMap = new HashMap<>();

		if (null != map && !map.isEmpty()) {
			pMap.putAll(map);
		}

		// pMap.put("Accept-Encoding", "gzip"); //请求定义gzip,响应也是压缩包
		pMap.put("connection", "Keep-Alive");
		pMap.put("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
		pMap.put("Content-Type", "application/json;charset=utf-8");
		return pMap;
	}

    /**
     * Description: restTemplate GET 请求<br>
     *
     * @author zhangpzh<br>
     * @param url 地址
     * @return <br>
     */
    public static String doGet(String url) {
        try {
            return restTemplate.getForObject(url, String.class);
        } catch (Exception e) {
            LOGGER.debug("GET请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    /*************************************** 国政通信息校验接口(新) ***************************************/

    /**
     *
     * @param url 地址
     * @param param 参数
     * @param isproxy 代理
     * @param headMap 请求头塞值
     * @return 返回值
     */
    public static String sendPostWithHead(String url, String param, boolean isproxy,Map<String,String> headMap) {
        LOGGER.info("请求url：{},入参：{},isproxy:{}",url,param,isproxy);
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder sb = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST"); // POST方法

            // 设置通用的请求属性

            for (Map.Entry<String, String> entry : setProperty(headMap).entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.connect();

            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
            // 发送请求参数
            out.write(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK
                    || conn.getResponseCode() == HttpURLConnection.HTTP_CREATED
                    || conn.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            } else {
                in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
            }
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
        } catch (Exception e) {
            LOGGER.error("发送 POST 请求出现异常！{}", e.getMessage());
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                LOGGER.error(ex.getMessage());
            }
        }
        return sb.toString();
    }
/******************************************************************推送数字券订单至集团*****************************************************************************/
    public static String sendPostWithAuth(String jsonString, String url, String auth) {
        try (CloseableHttpClient client = HttpClients.createDefault()){
            HttpPost post = new HttpPost(url);
            StringEntity s = new StringEntity(jsonString, StandardCharsets.UTF_8);
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json;charset=UTF-8");
            post.setEntity(s);
            post.setHeader("Content-Type", "application/json;charset=UTF-8");
            post.setHeader("X-APP-ID", ProvOrderConst.APP_ID);
            post.setHeader("X-APP-KEY",ProvOrderConst.APP_KEY);
            post.setHeader("X-CTG-Request-ID",UUID.randomUUID().toString());
            post.setHeader("X-CTG-Province-ID",ProvOrderConst.X_CTG_PROVINCE_ID);
            post.setHeader("X-CTG-Lan-ID",ProvOrderConst.X_CTG_LAN_ID);
            post.setHeader("x-auth-dq", auth);
            HttpResponse res = client.execute(post);
            if (res.getStatusLine().getStatusCode() == 200) {
                String result = EntityUtils.toString(res.getEntity());
                LOGGER.info("推送到集团接口的出参为:{}",result);
                return result;
            }else {
                LOGGER.info("推送到集团接口的状态码不为200");
            }
        } catch (Exception e) {
            LOGGER.error("sendPost请求出错：{}", url, e);
        }
        return "";
    }

    /*************************************** 3G升4G订单查询接口 ***************************************/

    private static final int RETRY_COUNT = 5;

    private static final int SO_TIMEOUT = 30 * 1000;

    private static final int CONNECTION_TIMEOUT = 30 * 1000;

    private static final String DEFAULT_CHARSET = "utf-8";

    private static final String DEFAULT_USER_AGENT = "userAgent";

    private static final String DEFAULT_CONTENT_TYPE = "application/json;charset=UTF-8";

    /**
     * 翼券平台接口的SYSCODE
     */
    private static final String E_COUPON_SYSCODE = "S032560";
    /**
     * 翼券平台接口的APPCODE
     */
    private static final String E_COUPON_APPCODE = "P204020201";
    /**
     * 翼券平台接口的秘钥
     */
    private static final String E_COUPON_APPKEY = "ebde671a1ebe11eeafd2fe10a3d6fc9a";
    /**
     * 翼券平台接口的秘钥版本号
     */
    private static final String E_COUPON_APP_KEY_VERSION = "00";
    /**
     * 翼券平台接口版本号
     */
    private static final String E_COUPON_VERSION_CODE = "0000";

    private static MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

    @SuppressWarnings("deprecation")
    public static String post(String url, String body, String userAgent, String contentType) throws HttpException, IOException {
        String responseBodyString = null;
        String uuid= UUIDHelper.getUUID();

        org.apache.commons.httpclient.HttpClient client = getHttpClientInstance();

        LOGGER.info("HttpUtility="+uuid+"=获取的参数==url="+url);
        LOGGER.info("HttpUtility="+uuid+"=获取的参数==body="+body);

        PostMethod method = new PostMethod(url);
        method.getParams().setSoTimeout(SO_TIMEOUT);
        method.addRequestHeader("User-Agent", StringUtils.isEmpty(userAgent) ? DEFAULT_USER_AGENT : userAgent);
        method.setRequestHeader("Content-Type", StringUtils.isEmpty(contentType) ? DEFAULT_CONTENT_TYPE : userAgent);
        method.setRequestBody(body);

        try {

            client.executeMethod(method);
            responseBodyString = method.getResponseBodyAsString();

        } finally {
            method.releaseConnection();
        }

        LOGGER.debug("HttpUtility="+uuid+"=返回的参数==response="+responseBodyString);
        return responseBodyString;
    }

    private static org.apache.commons.httpclient.HttpClient getHttpClientInstance() {
        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient(connectionManager);

        client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(
                        RETRY_COUNT, true));
        client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,DEFAULT_CHARSET);
        HttpConnectionManagerParams managerParams = client.getHttpConnectionManager().getParams();
        managerParams.setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,DEFAULT_CHARSET);
        managerParams.setConnectionTimeout(CONNECTION_TIMEOUT);  // 设置连接超时时间(单位毫秒)
        managerParams.setSoTimeout(SO_TIMEOUT);// 设置读数据超时时间(单位毫秒)
        return client;
    }

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param urlNameString 发送请求的URL
     *                      请求参数应该是 URL?name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String urlNameString, Map<String, String> headMap) {

        LOGGER.info("请求url："+urlNameString);
        StringBuilder sb = new StringBuilder();
        URLConnection connection = null;
        try {

            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("Content-Type", DEFAULT_CONTENT_TYPE);
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            // 自定义请求头
            if (null != headMap) {
                for (Map.Entry<String, String> entry : headMap.entrySet()) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 建立实际的连接
            connection.connect();

        } catch (Exception e) {
            LOGGER.error("发送GET请求出现异常！{0}", e);
        }

        // 定义 BufferedReader输入流来读取URL的响应
        if (null != connection) {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
            } catch (Exception e) {
                LOGGER.error("发送GET请求出现异常！{0}", e);
            }
        }

        return sb.toString();
    }

    /**
     * 翼券平台发送Get请求
     *
     * @param urlNameString 发送请求的URL
     *                      请求参数应该是 URL?name1=value1&name2=value2 的形式。
     * @param methodCode     接口方便编码
     * @return 所代表远程资源的响应结果
     */
    public static String sendGetECoupon(String urlNameString,String param,String methodCode) {
        urlNameString = urlNameString + param;
        LOGGER.info("翼券平台请求的URL:{}",urlNameString);
        StringBuilder sb = new StringBuilder();
        URLConnection connection = null;
        try {
            String date = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
            //获取报文流水号=sysCode(8位)+appCode(10位)+yyMMddHHmmss(12位)+GUID(32位)
            String transactionId = E_COUPON_SYSCODE+E_COUPON_APPCODE+date+genRandomGUID();
            //获取签名消息密钥版本号（2位）+ HEX小写(MD5（transactionId+电渠分配的密钥+Request URI+Request Body))
            LOGGER.info("生成Sign的RequestUrl:{}{}",E_COUPON_GENERATOR_SIGN_URL,param);
            String sign = E_COUPON_APP_KEY_VERSION+MD5Utils.mD5(transactionId + E_COUPON_APPKEY + E_COUPON_GENERATOR_SIGN_URL+param);
            String xAuthDq = String.format("%s;%s;%s;%s;%s;%s;%s",transactionId,E_COUPON_SYSCODE,E_COUPON_APPCODE,methodCode,
                    E_COUPON_VERSION_CODE,sign,new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
            LOGGER.info("发送翼券平台Get请求的x-auth-dq:{}",xAuthDq);
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("HOST","example.189.cn");
            connection.setRequestProperty("Content-Type", DEFAULT_CONTENT_TYPE);
            connection.setRequestProperty("Content-Length", "131");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("User-Agent", "baidu");
            connection.setRequestProperty("x-auth-dq",xAuthDq);


            // 建立实际的连接
            connection.connect();

        } catch (Exception e) {
            LOGGER.error("发送GET请求出现异常！{0}", e);
        }
        // 定义 BufferedReader输入流来读取URL的响应
        if (null != connection) {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
            } catch (Exception e) {
                LOGGER.error("读取URL响应出现异常！{0}", e);
            }
        }

        return sb.toString();
    }

    public static String doHttpPostMsg(String url, String requestString, String encoding) {
        try {
            LOGGER.info("请求url："+url);
            LOGGER.info("入参："+requestString);
            HttpPost post = new HttpPost(url);
            StringEntity entiy = new StringEntity(requestString, HttpConstant.UTF_ENCODING);
            post.setEntity(entiy);
            post.setHeader("Content-Type", "application/json; charset=UTF-8");
            HttpResponse response = httpClient.execute(post);
            org.apache.http.HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, encoding);
            return result;
        } catch (Exception e) {
            LOGGER.debug("HttpClient Post请求出错：{}", url, e);
        }
        return Strings.EMPTY;
    }

    /**
     * 使用httpclint 发送文件，如果不传输文件，直接设置fileParams=null，
     * 如果不设置请求头参数，直接设置headerParams=null，就可以进行普通参数的POST请求了
     *
     * @param url          请求路径
     * @param fileParams   文件参数
     * @param otherParams  其他字符串参数
     * @param headerParams 请求头参数
     * @return
     */
    public static String uploadFile(String url, Map<String, MultipartFile> fileParams, Map<String, String> otherParams, Map<String, String> headerParams) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = getHttpPost(url, headerParams);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(StandardCharsets.UTF_8);
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//加上此行代码解决返回中文乱码问题
            extracted(fileParams, builder);
            //    字节传输http请求头(application/json)
            ContentType contentType = ContentType.create("application/json", StandardCharsets.UTF_8);
            if (otherParams != null && otherParams.size() > 0) {
                for (Map.Entry<String, String> e : otherParams.entrySet()) {
                    String value = e.getValue();
                    if (!StringUtils.isEmpty(value)) {
                        builder.addTextBody(e.getKey(), value, contentType);// 类似浏览器表单提交，对应input的name和value
                    }
                }
            }
            org.apache.http.HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            org.apache.http.HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private static void extracted(Map<String, MultipartFile> fileParams, MultipartEntityBuilder builder) throws IOException {
        //    文件传输http请求头(multipart/form-data)
        if (fileParams != null && fileParams.size() > 0) {
            for (Map.Entry<String, MultipartFile> e : fileParams.entrySet()) {
                String fileParamName = e.getKey();
                MultipartFile file = e.getValue();
                if (file != null) {
                    String fileName = file.getOriginalFilename();
                    builder.addBinaryBody(fileParamName, file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
                }
            }
        }
    }

    private static HttpPost getHttpPost(String url, Map<String, String> headerParams) {
        HttpPost httpPost = new HttpPost(url);
        //设置请求头
        if (headerParams != null && headerParams.size() > 0) {
            for (Map.Entry<String, String> e : headerParams.entrySet()) {
                String value = e.getValue();
                String key = e.getKey();
                if (!StringUtils.isEmpty(value)) {
                    httpPost.setHeader(key, value);
                }
            }
        }
        return httpPost;
    }

    /**
     * @Description  如意接口http-post请求
     * @Param url 请求地址
     * @Param requestString 请求参数
     * @Param encoding 编码
     * @Param regionId 属地id
     * @Param staffCode 工号
     * @Param appSwitch
     * @return {@link String}
     * @authon jzd
     * @Date 2023/11/19 19:25
     */
    public static String doHttpGet2Ry(String url, String requestString,
                                      String regionId, String staffCode,String appSwitch) {
        CloseableHttpClient httpClient = null;
        try {
            HttpGetWithEntity httpGetWithEntity = new HttpGetWithEntity(url);
            org.apache.http.HttpEntity httpEntity = new StringEntity(requestString, ContentType.APPLICATION_JSON);
            httpGetWithEntity.setEntity(httpEntity);
            httpGetWithEntity.addHeader("Content-Type", "application/json;charset=utf-8");
            httpGetWithEntity.addHeader("X-CTG-Request-ID", UUID.randomUUID().toString());
            //生产 KFMH 客服门户  XABB 小A伴伴  KFGD 客服工单
            if(!StringUtils.isEmpty(appSwitch) && (appSwitch.equals("KFMH") || appSwitch.equals("XABB") || appSwitch.equals("KFGD"))){
                httpGetWithEntity.addHeader("X-APP-ID", RyUrlConstants.KF_X_APP_ID);
                httpGetWithEntity.addHeader("X-APP-KEY", RyUrlConstants.KF_X_APP_KEY);
                httpGetWithEntity.addHeader("appKey", RyUrlConstants.KFAPPKEY);
            }else{
                httpGetWithEntity.addHeader("X-APP-ID", RyUrlConstants.X_APP_ID);
                httpGetWithEntity.addHeader("X-APP-KEY", RyUrlConstants.X_APP_KEY);
                httpGetWithEntity.addHeader("appKey", RyUrlConstants.APPKEY);
            }
            httpGetWithEntity.addHeader("systemId", RyUrlConstants.SYSTEMID);
            httpGetWithEntity.addHeader("regionId", regionId);
            httpGetWithEntity.addHeader("staffCode", staffCode);

            httpGetWithEntity.setConfig(RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).setConnectionRequestTimeout(30000).build());
            httpClient = createSSLClientDefault();


            CloseableHttpResponse response = httpClient.execute(httpGetWithEntity);
            org.apache.http.HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            }
        } catch (Exception e) {
            LOGGER.error("如意{}接口出错：{}",url,e.getMessage(),e);
        } finally {
            if(httpClient != null){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    LOGGER.error("httpClient关闭失败，"+e.getMessage(),e);
                }
            }
        }
        return Strings.EMPTY;
    }
    
    public static String postForEntity(String url, HttpEntity<?> entity){
//        ResponseEntity<String> response = restTemplate.postForEntity(url,entity, String.class);
        
    	ResponseEntity<String> response =  restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

    	return response.getBody();
    }
}
